package proxyServer;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

public class ProxyThread extends Thread {
	Socket clientSocket, serverSocket;
	String hostname;

	ProxyThread(Socket in) {
		clientSocket = in;
	}

	// Overwritten run() method of thread,
	// does the data transfers
	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Thread#run()
	 */
	@Override
	public void run() {
		byte[] buffer = new byte[1024];
		int n;
		try {

			InputStream inputStreamFromClient = clientSocket.getInputStream();
			n = inputStreamFromClient.read(buffer);
			ProxyHttpRequest pr = new ProxyHttpRequest();
			if (!pr.parse(buffer))
				return; //
			System.out.println(new String(buffer));

			System.out.println("Connecting to host:" + pr.getHost()
					+ " ;port: " + pr.getPort());

			serverSocket = new Socket(pr.getHost(), pr.getPort());

			// forward the request from client to server
			OutputStream outStreamToServer = serverSocket.getOutputStream();
			System.out.println("Program is forward request to server . . . ");
			InputStream inputFromServer = serverSocket.getInputStream();
			OutputStream outToClient = clientSocket.getOutputStream();
			ProxyHttpReply py;
			while (true) {

				try {
					outStreamToServer.write(buffer, 0, n);
					outStreamToServer.flush();

					py = new ProxyHttpReply();
					int line = 0;
					int length = 0;
					do {
						Thread.yield();
						n = inputFromServer.read(buffer);
						line += n;
						if (n > 0) {
							outToClient.write(buffer, 0, n);
							if (!py.getHasHeader()) {
								py.parse(buffer);
								length = py.getContentLength();
							}
						}
					} while (length > line);

					try {
						outToClient.flush();
					} catch (Exception e11) {
					}
					if (pr.isCloseConnection() || py.isCloseConenction()) {
						System.out.println("Close:" + pr.getHost() + " ;port: "
								+ pr.getPort());
						return;
					}

					clientSocket.setSoTimeout(py.getTimeout());

				} catch (SocketTimeoutException ex) {
					return;
				}
			}

		} catch (ArrayIndexOutOfBoundsException e) {
			System.err.println("Error: Invalid memory.");
			return;
		} catch (UnknownHostException e) {
			System.err.println(e.toString());
			return;
		}

		catch (IOException e) {
			// TODO: handle exception
			System.err.println(e.toString());
			return;
		}

		finally {
			try {
				clientSocket.close();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
	}
}
